/*
 * src/lexical/la_init.c
 * 
 * Harry Wei <harryxiyou@gmail.com> (C) 2012
 *
 * Do some lexical init stuffs, these codes are under GPL.
 */
#include <stdio.h>
#include <glib.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
#include "cp_ctrl.h"

#define		TABLE		(1)
#define 	CHAR		(2)

/* flag: 1 is 'struct table *', 2 is 'char *' */
static int allocate_buff(void **buff, int size, int flag) {
	g_message("enter func %s", __func__);
	if (1 == flag) {
		(*buff) = (struct table *)g_malloc0(sizeof(struct table) * size);
		if (NULL == buff) {
			g_message("%s -- Allocate error!", __func__);
			return -1;
		}
	} else if (2 == flag) {
		(*buff) = (char *)g_malloc0(sizeof(char) * size);
		if (NULL == buff) {
			g_message("%s -- Allocate error!", __func__);
			return -1;
		}
	} else {
		g_message("No this kind of MEM type!");
		return -1;
	}
	g_message("leave func %s", __func__);
	return 0;
}

#if 0
static int textbuf2ctrl(struct la *ctrl, char *filename, char *buf) {
	g_message("enter func %s", __func__);
	if (NULL == ctrl || NULL == filename || NULL == buf) {
		g_message("%s -- Parameter error!", __func__);
		return -1;
	}
	g_message("%s -- ctrl[%p], filename[%s], buf[%p]", __func__, ctrl, filename, buf);
	int i = 0;
	char *endptr = NULL;
	gchar **v = g_strsplit(buf, "@@##$$", 1024);
	//gchar *_filename = g_strdup(filename);
	if (TRUE == g_str_has_prefix(filename, KEYFILE)) {
		g_message("%s -- keyfile branch, v[0] is %s", __func__, v[0]);
		g_message("%s -- keyword_buf[%p]", __func__, ctrl->keyword_buff);
		struct table *_buf = (struct table *) ctrl->keyword_buff;
		g_message("%s -- keyword_buf[%p]", __func__, _buf);
		ctrl->kd_amount = g_strv_length(v) - 1;
		for (i = 1; i < g_strv_length(v) - 1; i++) {
			_buf->code = strtoul(v[0], &endptr, 0) ;
			sprintf(_buf->ch, "%s", v[i]);
			_buf += 1;
		}
	} else if (TRUE == g_str_has_prefix(filename, DELIMITERFILE)) {
		ctrl->dt_amount = g_strv_length(v) - 1;
		struct table *_buf = (struct table *) ctrl->delimiter_buff;
		for (i = 1; i < g_strv_length(v) - 1; i++) {
			_buf->code = strtoul(v[0], &endptr, 0) ;
			sprintf(_buf->ch, "%s", v[i]);
			_buf += 1;
		}
	} else if (TRUE == g_str_has_prefix(filename, OPERATORFILE)) {
		ctrl->op_amount = g_strv_length(v) - 1;
		struct table *_buf = (struct table *) ctrl->operator_buff;
		for (i = 1; i < g_strv_length(v) - 1; i++) {
			_buf->code = strtoul(v[0], &endptr, 0) ;
			sprintf(_buf->ch, "%s", v[i]);
			_buf += 1;
		}
	} else {
		g_message("%s -- error, No this kind of type!", __func__);
		return -1;
	}
	g_strfreev(v);
	g_message("leave func %s", __func__);
	return 0;
}

static int read_contents(struct la *ctrl, char *filename) {
	g_message("enter func %s", __func__);
	if (NULL == ctrl || NULL == filename) {
		g_message("%s -- Parameter error!", __func__);
		return -1;
	}
	char buf[BUF_LEN];
	memset(buf, '\0', BUF_LEN);
	int ret = 0;
	int fd = open(filename, O_RDONLY);
	if (fd == -1) {
		g_message("%s -- Read file %s error!", __func__, filename);
		return -1;
	}
	struct stat fst; //file stat
	memset(&fst, 0, sizeof(struct stat));
	fstat(fd, &fst);
	/*XXX buf can not beyond length of BUF_LEN*/
	if (fst.st_size != read(fd, buf, fst.st_size)) { 
		g_message("%s -- read file %s error!", __func__, filename);
		return -1;
	}
	g_message("%s -- file %s's contents are [%s]", __func__, filename, buf);
	close(fd);
	ret = textbuf2ctrl(ctrl, filename, buf);
	g_assert(ret == 0);
	g_message("leave func %s", __func__);
	return 0;
}
#endif

int la_init(struct la *ctrl) {
	g_message("enter func %s", __func__);
	if (NULL == ctrl) {
		g_message("%s -- Parameter error!", __func__);
		return -1;
	}
#if 0
	if (TRUE != g_str_has_suffix(filename, "c")) {
		g_message("%s -- This is not a c file!", __func__);
		return -1;
	}
#endif
	int ret = 0;
	/*XXX handle ret value */
	ret = allocate_buff((void **) &ctrl->keyword_buff, TABLE_SIZE, TABLE);
	g_assert(ret == 0);
	ret = allocate_buff((void **) &ctrl->operator_buff, TABLE_SIZE, TABLE);
	g_assert(ret == 0);
	ret = allocate_buff((void **) &ctrl->delimiter_buff, TABLE_SIZE, TABLE);
	g_assert(ret == 0);
	ret = allocate_buff((void **) &ctrl->const_buff, TABLE_SIZE, TABLE);
	g_assert(ret == 0);
	ret = allocate_buff((void **) &ctrl->identifier_buff, TABLE_SIZE, TABLE);
	g_assert(ret == 0);
	ret = allocate_buff((void **) &ctrl->lexical_buff, TABLE_SIZE, TABLE);
	g_assert(ret == 0);
	ret = allocate_buff((void **) &ctrl->buff, BUF_LEN, CHAR);
	g_assert(ret == 0);
	ret = read_contents(ctrl, KEYFILE);
	g_assert(ret == 0);
#if 0
	int i = 0;
	struct table *_buf = (struct table *) ctrl->keyword_buff;
	//ctrl->kd_amount = g_strv_length(v) - 1;
	for (i = 0; i < ctrl->kd_amount - 1; i++) {
		g_message("%s -- code [%d] ch [%s]", __func__, _buf->code, _buf->ch);
		_buf += 1;
	}
#endif
	ret = read_contents(ctrl, DELIMITERFILE);
	g_assert(ret == 0);
	ret = read_contents(ctrl, OPERATORFILE);
	g_assert(ret == 0);
#if 0
	int i = 0;
	struct table *_buf = (struct table *) ctrl->operator_buff;
	//ctrl->kd_amount = g_strv_length(v) - 1;
	for (i = 0; i < ctrl->op_amount - 1; i++) {
		g_message("%s -- code [%d] ch [%s]", __func__, _buf->code, _buf->ch);
		_buf += 1;
	}
#endif
	g_message("leave func %s", __func__);
	return 0;
}
